package com.example.customannotate.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * 实现@RunTimeRecord注解功能的切面类
 *
 * @author zhouzhaodong
 */
@Component
@Aspect
@Slf4j
public class RunTimeRecordAop {

    @Around("@annotation(com.example.customannotate.aop.RunTimeRecord)")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法信息
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 获取方法名
        String methodName = methodSignature.getName();
        // 获取方法参数名
        String[] paramNames = methodSignature.getParameterNames();
        // 获取方法参数值
        Object[] args = joinPoint.getArgs();

        // 获取注解信息
        RunTimeRecord runTimeRecord = methodSignature.getMethod().getAnnotation(RunTimeRecord.class);
        String value = runTimeRecord.value();
        String level = runTimeRecord.level();

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < paramNames.length; i++) {
            sb.append("<").append(paramNames[i]).append(":").append(args[i]).append(">");
        }

        // 执行开始前打印日志
        String startMsg = "[START] TS: " + System.currentTimeMillis() + " Value: " + value + " <" + level + ">" + " MethodName: " + methodName + " Param: " + sb;
        log.info(startMsg);

        // 调用目标方法
        Object res = "Method Run Failed";
        try {
            // 获取方法正常的返回值
            res = joinPoint.proceed();
        } catch (Exception e) {
            // 如果出现异常，可以在这里重新拼接返回信息
            log.error("Happen Error: {}", e.getMessage());
        }

        // 执行完成后打印日志
        String endMsg = "[END] TS: " + System.currentTimeMillis() + " Value: " + value + " <" + level + ">" + " MethodName: " + methodName + " Result: " + res;
        log.info(endMsg);
        return res;
    }

}
